/**
 * ScoreScene.m
 * 
 * Revision History: 
 *
 * Date     Author       Version   Changes
 * ======== ============ ========= ================================================================
 * 03/26/10 Steve Hu     2.0       Initial version.
 * 03/26/10 Judy Cheng   2.1       Add openWeb function so that the user can enter the Sigma top 25
 *								   score website to see.
 * 04/10/10 Steve Hu	 3.0	   Added an upload condition so that user with score of zero cannot
 *							       upload his score.
 * 05/29/10 Robin Mahony 3.1       Add openWeb2 function so that the user can go to google code website
 * ======== ============ ========= ================================================================
 *
 */

#import "ScoreScene.h"
#import <SystemConfiguration/SystemConfiguration.h>
#include <netdb.h>

@implementation ScoreScene
/* This method initializes a Sprite object, which loads the background image. Then it sets the 
 Sprite's on-screen location to the middle of the screen. Finally, it adds the background sprite 
 to the scene and then proceed to instantiate the ScoreLayer class and add it to the scene.  */
- (id) init 
{
    self = [super init];
    
	if (self != nil) 
	{
		Sprite *bg = [Sprite spriteWithFile:@"ViewScoreBackground.png"];
		[bg setPosition:ccp (160, 240) ];
		[self addChild:bg z:0];
		
		/* Set the depth ordering to 1, so everything will be on top of this background layer  */
        Layer *layer = [ScoreLayer node];
		[self addChild:layer z:1];
    }
    return self;
}


/* This method removes all objects added to the scene, indicating you want Cocos2D to “clean up” by 
 releasing the objects as well, and then you must call the dealloc method of the superclass  */
- (void) dealloc 
{
	[self removeAllChildrenWithCleanup:YES];
	[super dealloc];
}


@end
@interface ScoreLayer (Private)
- (void) showScore;
- (void) loadScore;
- (void) processTaps;
- (void) uploadScore;
- (BOOL) connectedToNetwork;
- (void) exitScore;
- (IBAction) openWeb;
- (IBAction) openWeb2;
@end

@implementation ScoreLayer
- (id) init 
{
    self = [super init];

	if (self != nil) 
	{
		/* This tells Cocos2d to call our touch event handlers.  */
		isTouchEnabled = YES;
		[self showScore];		
    }
	return self;
}

- (void) dealloc 
{
	[self removeAllChildrenWithCleanup:YES];
	[super dealloc];
}

/* This method is the score scene loop.  */
- (void) updateBoard:(ccTime)dt 
{
	[self processTaps];
}

- (void) showScore 
{
	/* Loads all scores first.  */
	[self loadScore];
	
	/* Initialize each score's row coordinates.  */
	float start_y = 360.0f;
	float rowHeight = 50.0f;
	
	for (int i = 0; i < (numOfScore + 1); i++)
	{
		score_y_coord[i] = (start_y + 25) - i * rowHeight - 2.0f;
	}
	
	//for(NSMutableArray *highscore in highscores) {
	for (int i = 0; i < numOfScore; i++)
	{
		NSString *player = nameList[i];
		int score = scoreList [i];
		

		/* Intialize rank number, username, score labels for each score record.  */
		Label *rankLabel = [Label labelWithString:[NSString stringWithFormat:@"%d",(i + 1)]
						dimensions:CGSizeMake(30, 40) alignment:UITextAlignmentRight fontName:@"Arial" fontSize:14];
		[self addChild:rankLabel z:0];
		[rankLabel setRGB:255:255:255];
		rankLabel.position = ccp(15, start_y-i * rowHeight - 2.0f);
		
		Label *userNameLabel = [Label labelWithString:player dimensions:CGSizeMake(240, 40) 
						alignment:UITextAlignmentLeft fontName:@"Arial" fontSize:16];
		[self addChild:userNameLabel z:0];
		[rankLabel setRGB:255:255:255];
		userNameLabel.position = ccp(160, start_y - i * rowHeight);
		
		Label *scoreLabel = [Label labelWithString:[NSString stringWithFormat:@"%d",score] 
						dimensions:CGSizeMake(290, 40) alignment:UITextAlignmentRight fontName:@"Arial" fontSize:16];
		[self addChild:scoreLabel z:0];
		[scoreLabel setRGB:255:255:255];
		scoreLabel.position = ccp(160, start_y - i * rowHeight);
		
		/* Using GO TO WEBSITE to be the label for entering the website. */
		Label *webLabel = [Label labelWithString:@"Go to High Scores Website" fontName:@"Arial" fontSize:16];
		[webLabel setRGB:0 :0 :0];
		webLabel.position = ccp (160, 100); 
		[self addChild: webLabel];
		
		/* Using GO TO WEBSITE to be the label for entering the website. */
		Label *webLabel2 = [Label labelWithString:@"Go to Sigma Development Website" fontName:@"Arial" fontSize:12];
		[webLabel2 setRGB:0 :0 :0];
		webLabel2.position = ccp (160, 20); 
		[self addChild: webLabel2];
		
		
	}
	
	/* Create Upload and Back buttons with corresponding button images.  */
	MenuItem *uploadButton = [MenuItemImage itemFromNormalImage:@"upload_btn.png" selectedImage:@"upload_btn.png" 
						target:self selector:@selector(uploadCallback:)];
	MenuItem *backButton = [MenuItemImage itemFromNormalImage:@"back_btn.png" selectedImage:@"back_btn.png" 
						target:self selector:@selector(backCallback:)];

	Menu *menu = [Menu menuWithItems: uploadButton, backButton, nil];
	
	/* Set the padding between buttons.  */
	[menu alignItemsHorizontallyWithPadding:10];
	menu.position = ccp(160, 58);
	[self addChild:menu];
	

	/* Execute updateBoard 60 times per second.  */
	[self schedule:@selector(updateBoard:) interval: 1.0 / 60.0];
}

/* This method loads all the currently saved scores and their corresponding names.  */
- (void) loadScore 
{
	int memoryIndex = 0; /* Memory location index.  */
	for (int i = 0; i < numOfScore; i++)
	{
		memoryIndex = i + 1;
		scoreList[i] = [[NSUserDefaults standardUserDefaults]integerForKey:
						[NSString stringWithFormat:@"score%01dKey", memoryIndex]];
		nameList[i] = [[NSUserDefaults standardUserDefaults]stringForKey:
					   [NSString stringWithFormat:@"string%01dKey", memoryIndex]];
		
		/* Set the name to Sigma if no username found in memory.  */
		if (nameList[i] == nil)
		{
			nameList[i] = @"Sigma";
		}
	}
}



/* This method examines the touchType variable that was set earlier by the 
 ccTouchesEnded:withEvent: method. The code resets the touchType variable 
 immediately so that you don't forget and are ready for the next touch event.  */
- (void) processTaps 
{	
	/* Setup the highlighted index variable: highlighScore.  */
	if (touchType == score_0) 
	{
		touchType = kNone;
		highlightIndex = 0;
    } 
	else if (touchType == score_1) 
	{
		touchType = kNone;
		highlightIndex = 1;
	} 
	else if (touchType == score_2)
	{
		touchType = kNone;
		highlightIndex = 2;
	}
	else if(touchType == score_3)
	{
		touchType = kNone;
		highlightIndex = 3;
	}
	else if (touchType == score_4)
	{
		touchType = kNone;
		highlightIndex = 4;
	}
	else if(touchType == goToGCode)
	{
		touchType =nullType;
		[self openWeb2];
	}
	else if(touchType == goToWeb)
	{
		touchType =nullType;
		[self openWeb];
	}
	

}

/* This method draws a highlight on the touched score.  */
- (void) draw 
{
	
	glColor4ub(0,0,0,50);
	
	/* Setup the drawing coordinate.  */
	float w = 320.0f;
	float h = 35.0f;
	float x = (320.0f - w) / 2;
	float y = 353.0f - highlightIndex * (h + 15);

	GLfloat vertices[4][2];	
	GLubyte indices[4] = { 0, 1, 3, 2 };
	
	glVertexPointer(2, GL_FLOAT, 0, vertices);
	glEnableClientState(GL_VERTEX_ARRAY);
	
	vertices[0][0] = x;		vertices[0][1] = y;
	vertices[1][0] = x + w;	vertices[1][1] = y;
	vertices[2][0] = x + w;	vertices[2][1] = y + h;
	vertices[3][0] = x;		vertices[3][1] = y + h;
	
	glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
	
	glDisableClientState(GL_VERTEX_ARRAY);	
}


/* Define the single tap region, and listen to the events generated 
 when the user lifts their finger off the screen.  */
- (BOOL) ccTouchesEnded:(NSSet *) touches withEvent:(UIEvent *) event 
{
	
	UITouch *touch = [touches anyObject];
	CGPoint point = [touch locationInView: [touch view]];

	/* To compare Cocos2D Sprite positions to UITouch coordinates,
	 we need to flip UITouch y coordinate upside down for portrait mode.  */
	point.y = 480 - point.y;

    /* Define the left/right/down buttons control area to match the background image.  */
	if (((int) point.y > score_y_coord[1]) && ((int) point.y < score_y_coord[0])) 
	{
		touchType = score_0;
	}
	else if (((int) point.y > score_y_coord[2]) && ((int) point.y < score_y_coord[1]))
	{
		touchType = score_1;
	}
	else if (((int) point.y > score_y_coord[3]) && ((int) point.y < score_y_coord[2]))
	{
		touchType = score_2;
	}
	
	else if (((int) point.y > score_y_coord[4]) && ((int) point.y < score_y_coord[3]))
	{
		touchType = score_3;
	}
	
	else if (((int) point.y > score_y_coord[5]) && ((int) point.y < score_y_coord[4]))
	{
		touchType = score_4;
	}
	
	else if (((int) point.y > 90) && ((int) point.y < 110) && ((int) point.x > 100) && ((int) point.x < 260)) 
	{
		touchType = goToWeb;
	}
	
	else if (((int) point.y > 15) && ((int) point.y < 25) && ((int) point.x > 100) && ((int) point.x < 260)) 
	{
		touchType = goToGCode;
	}
	return kEventHandled;
}


/* Upload button event handler for uploading the highlighed score.  */
- (void) uploadCallback:(id)sender 
{
	if (scoreList[highlightIndex] > 0)
	{
		[self uploadScore];
	}
	else 
	{
		/* Do not allow score to be uploaded if it is ZERO.  */
		UIAlertView *alert = [[UIAlertView alloc] 
				 initWithTitle:[NSString stringWithFormat:@"%@'s score: %05d", 
								nameList[highlightIndex], scoreList[highlightIndex]]
				 message:@"Sorry! Score of ZERO cannot be uploaded."
				 delegate:self 
				 cancelButtonTitle:@"OK" 
				 otherButtonTitles: nil];
		[alert show];
		[alert release];
	}

}

/* Back button event handler for returning to the main menu.  */
- (void) backCallback:(id)sender 
{
	[self exitScore];
}

/* This method uses HTTP Post method to send score to php website which handle database insert.  */
- (void) uploadScore
{	
	UIAlertView *alert = nil;
	
	if ([self connectedToNetwork] )
	{
		
		/* Column names in the score_data table.  */
		NSString *usernameDB = @"UserName"; 
		NSString *scoreDB = @"Score";

		/* Retrieve the username and score according to the highlighted index.  */
		NSString *userName = nameList[highlightIndex];
		int score = scoreList[highlightIndex];
		
     	NSURL *url = [[NSURL alloc] initWithString:scoreURL];
		NSMutableURLRequest *req = [[NSMutableURLRequest alloc] 
									initWithURL:url];
		/* Use POST method instead of GET to hide data.  */
		[req setHTTPMethod:@"POST"]; 
		
		
		/* Insert corresponding score and username to the HTTPPostHeader.  */
		NSString *paramDataString = [NSString stringWithFormat:@"%@=%@&%@=%05d", 
									 usernameDB, userName, scoreDB, score];
		NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding];
		[req setHTTPBody: paramData];	
		
		NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:req delegate:self];
		
		/* Check if upload successfully or not.  */
		if (theConnection)
		{
			NSLog(@"theConnection = %@", theConnection);  
			alert = [[UIAlertView alloc] 
					 initWithTitle:[NSString stringWithFormat:@"%@'s score: %05d", userName, score]
					 message:@"Uploaded successfully"
					 delegate:self 
					 cancelButtonTitle:@"OK" 
					 otherButtonTitles: nil];
		} 
		else 
		{
			alert = [[UIAlertView alloc] 
					 initWithTitle:@"Upload Failed" 
					 message:@"Server may be busy.  Please try again."
					 delegate:self 
					 cancelButtonTitle:@"Quit" 
					 otherButtonTitles: nil];
		}
		[alert show];
		[alert release];
		[url release];
		[req release];

	}
	
	else
	{
		alert = [[UIAlertView alloc] 
				 initWithTitle:@"Upload Failed" 
				 message:@"No internet connection detected."
				 delegate:self 
				 cancelButtonTitle:@"Quit" 
				 otherButtonTitles: nil];
		[alert show];
		[alert release];
		
	}
}


/* This method checks to ensure an internet connection is available on the device.  
 Returns NO if no connection exits,  YES if there is a connection.  */
- (BOOL) connectedToNetwork 
{
	/* Create zero addy.  */
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;
    
    /* Recover reachability flags.  */
    SCNetworkReachabilityRef defaultRouteReachability 
	= SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;
    
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
    
    if (!didRetrieveFlags)
    {
        printf("Error. Could not recover network reachability flags\n");
        return NO;
    }
    
    BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
    BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0);
    return (isReachable && !needsConnection) ? YES : NO;
}

/* This methods exit the Score scene and enter the Menu Scene.  */
- (void) exitScore 
{
	/* Stop the score loop.  */
	[self unschedule:@selector (updateFrame:)];
	[[Director sharedDirector] replaceScene: [MenuScene node]];
}

/* This method switchs to safari and open the Sigma top 25 high score website. */
- (IBAction) openWeb
{
	if ([self connectedToNetwork] )
	{
		[[Director sharedDirector] pause];
		[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://sigma-topscore.comyr.com/sigma_web/top_scores.php"]];
	}
}

/* This method switchs to safari and open the Sigma development website. */
- (IBAction) openWeb2
{
	if ([self connectedToNetwork] )
	{
		[[Director sharedDirector] pause];
		[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://code.google.com/p/s-i-g-m-a"]];
	}
}

@end
